﻿using System;
using CLDataAppManagementTS;
using CLVisionMQTT;
using NationalInstruments.TestStand.Interop.API;
using Newtonsoft.Json.Linq;

namespace CLVisionEICS
{
    public abstract class CLEICSClientBase : ICLEICSClient
    {
        protected MQTTClient mQTTClient;

        public abstract JObject eicsJson { get; set; }

        private Action<string> _eventReceivedMessage;
        public Action<string> EventReceivedMessage
        {
            get => _eventReceivedMessage;
            set => _eventReceivedMessage = value;
        }

        private Action<string> _eventDisconnected;
        public Action<string> EventDisconnected
        {
            get => _eventDisconnected;
            set=> _eventDisconnected = value;
        }
       

        public abstract bool IntMqttClient(string server, int port, string username, string password, string topicName, string clientId, out int ErrorCode, out string ErrorText, string cdatFilePath = null);
       

        public virtual bool PublishData(string topicName, string mesData, MQTTnet.Protocol.MqttQualityOfServiceLevel qos, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(PublishData)}: Start!";
            try
            {
                bool ret = mQTTClient.PublishData(topicName, mesData, qos, out ErrorCode, out ErrorText);
                return ret && ErrorCode != -1;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(PublishData)}: Fail! " + ex.Message;
                return false;
            }
        }

        public virtual bool SubscribeTopic(out int ErrorCode, out string ErrorText, params string[] topicNames)
        {
            ErrorCode = 0;
            ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(SubscribeTopic)}: Start!";
            try
            {
                bool ret = mQTTClient.SubscribeTopic(out ErrorCode, out ErrorText, topicNames);
                return ret && ErrorCode != -1;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(SubscribeTopic)}: Fail! " + ex.Message;
                return false;
            }
        }

        public virtual bool UnsubscribeTopic(out int ErrorCode, out string ErrorText, params string[] topicNames)
        {
            ErrorCode = 0;
            ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(UnsubscribeTopic)}: Start!";
            try
            {
                bool ret = mQTTClient.UnsubscribeTopic(out ErrorCode, out ErrorText, topicNames);
                return ret && ErrorCode != -1;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(UnsubscribeTopic)}: Fail! " + ex.Message;
                return false;
            }
        }

        public virtual bool DisconnectMqttClient(out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(DisconnectMqttClient)}: Start!";
            try
            {
                bool ret = mQTTClient.DisconnectMqttClient(out ErrorCode, out ErrorText);
                return ret && ErrorCode != -1;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(DisconnectMqttClient)}: Fail! " + ex.Message;
                return false;
            }
        }

        public bool ReceiveDataWithTimeout(out string receivedMessage, out int ErrorCode, out string ErrorText, int timeoutMs = 3000, int pollIntervalMs = 50)
        {
            ErrorCode = 0;
            ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(ReceiveDataWithTimeout)}: Start!";
            receivedMessage = string.Empty;
            try
            {
                return mQTTClient.ReceiveDataWithTimeout(out receivedMessage, out ErrorCode, out ErrorText, timeoutMs, pollIntervalMs);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(CLEICSClientBase)}:{nameof(ReceiveDataWithTimeout)}: Fail! " + ex.Message;
                receivedMessage = string.Empty;
                return false;
            }
        }

        public abstract bool SetEICSValueByKey(string key, object value, out int ErrorCode, out string ErrorText);

        public abstract bool SetEICSValueByArrayString(string value, out int ErrorCode, out string ErrorText);

        public abstract bool SetEICSValuesByKeys(PropertyObject values, out int ErrorCode, out string ErrorText);

        public abstract bool SetEICSValueByKey(PropertyObject key, out int ErrorCode, out string ErrorText);
       
    }
}